package com.hmsm.sys.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import com.hmsm.server.base.BaseService;
import com.hmsm.server.common.AllContext;
import com.hmsm.server.util.QueryResult;
import com.hmsm.sys.bean.LocalDept;
import com.hmsm.sys.bean.LocalRole;
import com.hmsm.sys.bean.LocalUser;
import com.hmsm.sys.dao.FuncInfoDao;
import com.hmsm.sys.dao.RoleFuncDao;
import com.hmsm.sys.dao.RoleInfoDao;
import com.hmsm.sys.po.FuncInfo;
import com.hmsm.sys.po.RoleFunc;
import com.hmsm.sys.po.RoleInfo;
import com.lzyyj.common.Page;
import com.lzyyj.gmis.base.model.Purview;
import com.lzyyj.gmis.base.service.IHaveRoleFuncs;
import com.lzyyj.gmis.base.service.IModuleService;

@Service
public class RoleInfoService<U extends LocalUser> extends BaseService<RoleInfo, Integer, U, RoleInfo> implements IModuleService,IHaveRoleFuncs,IRoleInfoService<RoleInfo, Integer, U> {

	private static final Log log = LogFactory.getLog(RoleInfoService.class);
	
	private static Map<Integer, RoleInfo> roleMap;
	
	private static Map<Integer, FuncInfo> funcMap;
	
	private static Map<Integer, FuncInfo> rootMap;
	
	private static Map<String, FuncInfo> funcPathMap;
	
	public RoleInfoDao getBaseDao(){
		return (RoleInfoDao) super.baseDao;
	}
	
	@Resource
	public void setBaseDao(RoleInfoDao baseDao){
		super.baseDao = baseDao;
	}
	
	@Resource
	private FuncInfoDao funcInfoDao;
	
	public FuncInfoDao getFuncInfoDao() {
		if (funcInfoDao == null){
			funcInfoDao = (FuncInfoDao) AllContext.getBeanService(FuncInfoDao.class);
		}
		return funcInfoDao;
	}

	public void setFuncInfoDao(FuncInfoDao funcInfoDao) {
		this.funcInfoDao = funcInfoDao;
	}
	
	@Resource
	private RoleFuncDao roleFuncDao;

	public RoleFuncDao getRoleFuncDao() {
		return roleFuncDao;
	}

	public void setRoleFuncDao(RoleFuncDao roleFuncDao) {
		this.roleFuncDao = roleFuncDao;
	}
	
	@Resource
	private ILogInfoService logInfoService;
	
	public ILogInfoService getLogInfoService() {
		return logInfoService;
	}

	public void setLogInfoService(ILogInfoService logInfoService) {
		this.logInfoService = logInfoService;
	}

	@Resource
	private IUserRoleService userRoleService;

	public IUserRoleService getUserRoleService() {
		if (userRoleService==null){
			userRoleService = (IUserRoleService) AllContext.getBeanService(IUserRoleService.class);
		}
		return userRoleService;
	}

	public void setUserRoleService(IUserRoleService userRoleService) {
		this.userRoleService = userRoleService;
	}
	
	@Resource
	private IDeptInfoService deptInfoService;

	public IDeptInfoService getDeptInfoService() {
		return deptInfoService;
	}

	public void setDeptInfoService(IDeptInfoService deptInfoService) {
		this.deptInfoService = deptInfoService;
	}

	public static final String RANGE_ROLE_MANAGE = "RoleManageRange";						// 角色管理范围
	
	public static final String RANGE_ROLE_MANAGE_ORG = "RoleManageOrgRange";				// 角色管理组织机构范围
	public static final String RANGE_ROLE_MANAGE_MODULE = "RoleManageModuleRange";			// 角色管理功能模块范围
	
	public static final String RIGHT_ROLE_MODULE_ADMIN = "ModuleAdmin";					// 功能模块管理员权限
	public static final String RIGHT_ROLE_MODULE_USER = "ModuleUser";						// 功能模块用户权限
	
	public static final String RIGHT_RANGE_DEFAULT_KEY = "DefautRange";					// 缺省的权限范围Key
	
	@Override
	public String getModuleName() {
		return "角色权限管理";
	}
	
	private static final List<Purview> funcGroup = new ArrayList<Purview>();
	
	@Override
	public List<Purview> getFuncGroup(){
		return funcGroup;
	}

	private static final List<String> roleList = new ArrayList<String>();
	
	@Override
	public List<String> getRoleList(){
		return roleList;
	}
	
	@Override
	public String getAdminRole() {
		// 声明业务管理角色
//		return ADMIN_ROLE_NAME;
		return null;
	}

	public static final Map<String, String[]> roleFuncs = new HashMap<String, String[]>();
	
	@Override
	public Map<String, String[]> getRoleFuncs() {
		return roleFuncs;
	}

	public RoleInfoService(){

		// 声明需注册的功能权限, 以后改为xml文件来定义
		Purview mainPurview = new Purview("系统管理", RIGHT_SYS_GROUP, "管理系统基本配置");
		List<Purview> purvies = mainPurview.getPurviews();
		// purvies.add(new Purview("组织机构管理", RIGHT_ORG_MANAGE, "管理组织机构")); 转由组织机构管理模块定义
		// purvies.add(new Purview("用户管理", RIGHT_USER_MANAGE, "管理系统用户"));	转由用户管理模块定义
		
		Purview purview= new Purview("角色权限管理", RIGHT_ROLE_MANAGE, "管理角色及权限");
		purvies.add(purview);

		Purview roleManageRange = new Purview("权限范围", RANGE_ROLE_MANAGE, "角色权限管理范围");
		purview.getPurviews().add(roleManageRange);
		
		Purview operationTypeRange = new Purview("功能模块范围", RANGE_ROLE_MANAGE_MODULE, "功能模块范围");
		roleManageRange.getPurviews().add(operationTypeRange);
		
		Purview roleOrgRange = new Purview("组织机构范围", RANGE_ROLE_MANAGE_ORG, "组织机构范围");
		roleManageRange.getPurviews().add(roleOrgRange);
		
		List<Purview> roleOrgRangeList = roleOrgRange.getPurviews();
		Purview orgRangeDept = new Purview("所属部门的", RoleInfoService.RIGHT_RANGE_ORG_DEPT, "可查看部门内的内容");
		roleOrgRangeList.add(orgRangeDept);
		Purview orgRangeOrg = new Purview("所属组织机构的", RoleInfoService.RIGHT_RANGE_ORG_ORG, "可查看组织机构内的内容");
		roleOrgRangeList.add(orgRangeOrg);
		Purview orgRangeAll = new Purview("所有的", RoleInfoService.RIGHT_RANGE_ORG_ALL, "可查看所有的内容");
		roleOrgRangeList.add(orgRangeAll);
		
		List<Purview> roleManageRanges = operationTypeRange.getPurviews();
		roleManageRanges.add(new Purview("功能模块管理员", RIGHT_ROLE_MODULE_ADMIN, "可管理其他功能模块管理员权限授权"));
		roleManageRanges.add(new Purview("功能模块用户", RIGHT_ROLE_MODULE_USER, "可管理其他功能模块的用户权限授权"));
		
		purvies.add(new Purview("管理员管理", RIGHT_ADMIN_MANAGE, "管理管理员"));
		purvies.add(new Purview("日志管理", RIGHT_LOG_MANAGE, "管理系统日志"));
		purvies.add(new Purview("消息管理", RIGHT_MESSAGE_MANAGE, "管理系统消息"));
		purvies.add(new Purview("系统管理员", RIGHT_SYS_MANAGE, "系统管理员"));
		funcGroup.add(mainPurview);
		
		// 声明系统用户管理员角色，并设置默认权限
		roleList.add(ADMIN_ROLE_NAME);
		roleFuncs.put(ADMIN_ROLE_NAME, new String[]{
				RIGHT_ROLE_MANAGE+"("+RIGHT_ROLE_MODULE_ADMIN+"_"+RIGHT_RANGE_ORG_DEPT+","+RIGHT_ROLE_MODULE_ADMIN+"_"+RIGHT_RANGE_ORG_ORG+","+RIGHT_ROLE_MODULE_ADMIN+"_"+RIGHT_RANGE_ORG_ALL+","+RIGHT_ROLE_MODULE_USER+"_"+RIGHT_RANGE_ORG_DEPT+","+RIGHT_ROLE_MODULE_USER+"_"+RIGHT_RANGE_ORG_ORG+","+RIGHT_ROLE_MODULE_USER+"_"+RIGHT_RANGE_ORG_ALL+")",
				RIGHT_ADMIN_MANAGE,
				RIGHT_LOG_MANAGE,
				RIGHT_MESSAGE_MANAGE,
				RIGHT_SYS_MANAGE
		});
		
	}
	
	@Override
	public void start() throws Exception {
		// 以系统管理员角色是否配置了系统管理员权限为标志来决定是否重新初始化各模块角色权限配置
		RoleFunc adminRoleFunc = null;

		// 管理员角色检查
		RoleInfo adminRole = getRoleByName(ADMIN_ROLE_NAME);
		if (adminRole!=null){
			// 系统管理权限组检查
			FuncInfo sysFuncGroup = getByGroupName("系统管理");
			if (sysFuncGroup!=null){
				// 系统管理权限检查
				FuncInfo adminFuncInfo = getSubFuncByFuncCode(sysFuncGroup, RIGHT_SYS_MANAGE);
				if (adminFuncInfo!=null){
					// 管理员管理权限授权检查
					adminRoleFunc = getRoleFunc(adminRole.getPkId(), adminFuncInfo.getPkId());
				}
			}
		}

		if (adminRoleFunc==null||adminRoleFunc.getState()!=1){
			getLogInfoService().log(this, "启动时重置了默认角色的权限配置");
			resetFuncAndRoles();
			adminRole = getRoleByName(ADMIN_ROLE_NAME);
			if (adminRole!=null){
				// 系统管理权限组检查
				FuncInfo sysFuncGroup = getByGroupName("系统管理");
				if (sysFuncGroup!=null){
					// 系统管理权限检查
					FuncInfo adminFuncInfo = getSubFuncByFuncCode(sysFuncGroup, RIGHT_SYS_MANAGE);
					if (adminFuncInfo!=null){
						addFuncForRoleId(adminFuncInfo.getPkId(), adminRole.getPkId());
					}
				}
			}
		}
	}

	@Override
	public void stop() {
	}

	/**
	 * 重置权限代码及系统功能角色权限配置
	 * @param adminRole
	 * @throws Exception
	 */
	public void resetFuncAndRoles() throws Exception {
		// 遍历所有提供了功能角色及权限代码声明接口的功能模块
		
		// 优先重置角色权限管理模块
		log.info("检查 "+getModuleName()+" 的角色权限配置");
		resetFuncAndRoles(this);

		for(Entry<String, IHaveRoleFuncs> serverEntry:AllContext.getAppContext().getBeansOfType(IHaveRoleFuncs.class).entrySet()){
			String serverName = serverEntry.getKey();
			IHaveRoleFuncs server = serverEntry.getValue();

			// 避免重复处理 角色权限管理 模块
			if(server!=this){

				log.info("检查 "+serverName+" 的角色权限配置");
				resetFuncAndRoles(server);
			}
			
		}
	}
	
	/**
	 * 重置功能模块相关功能权限、角色及角色权限
	 * @param server
	 * @param funcCodeMap
	 * @param funcIdMap
	 * @throws Exception
	 */
	private void resetFuncAndRoles(IHaveRoleFuncs server) throws Exception{
		/**
		 * 当前功能模块注册的功能有效功能权限名值表
		 */
		Map<String, Map<String, FuncInfo>> funcGroupMap = new HashMap<String, Map<String, FuncInfo>>();
		
		/**
		 * 当前功能模块注册的功能有效功能权限主键表
		 */
		Map<Integer, FuncInfo> funcIdMap = new HashMap<Integer, FuncInfo>();
		
		// 检查更新功能权限
		for (Purview purviewGroup: server.getFuncGroup()){
			String funcGroupName = purviewGroup.getName();
			// 检查及更新功能权限组
			FuncInfo funcGroup = getByGroupName(funcGroupName);
			if (funcGroup==null){
				funcGroup = new FuncInfo();
				funcGroup.setName(funcGroupName);
				funcGroup.setParentId(0);
				funcGroup.setFuncCode("");
				funcGroup = funcInfoDao.save(funcGroup);
			}
			
			Map<String, FuncInfo> funcCodeMap = new HashMap<String, FuncInfo>();
			funcGroupMap.put(funcGroupName, funcCodeMap);
			
			// 检查并更新功能权限组下的功能权限注册,不处理未声明的功能权限
			for(Purview funcPurview:purviewGroup.getPurviews()){
				String name = funcPurview.getName();
				String funcCode = funcPurview.getPurviewKey();
				
				FuncInfo func = getSubFuncByFuncCode(funcGroup, funcCode);
				if (func==null){
					func = new FuncInfo();
					func.setName(name);
					func.setParentId(funcGroup.getPkId());
					func.setFuncCode(funcCode);
					func = funcInfoDao.save(func);
				}else{
					if(!func.getName().equals(name)){
						func.setName(name);
						func = funcInfoDao.update(func);
					}
				}
				if (!funcCodeMap.containsKey(funcCode)){
					funcCodeMap.put(funcCode, func);
				}
				if (!funcIdMap.containsKey(func.getPkId())){
					funcIdMap.put(func.getPkId(), func);
				}
				
				// 检查及更新功能权限下的功能权限范围注册
				refreshFuncRangeType(func, funcPurview, funcIdMap, funcCodeMap);
			}
		}

		// 检查及更新功能模块下的各功能角色及其权限配置
		for (String roleName: server.getRoleList()){
			// 检查及更新功能角色
			RoleInfo roleInfo = getRoleByName(roleName);
			if (roleInfo==null){
				roleInfo = new RoleInfo();
				roleInfo.setName(roleName);
				roleInfo.setOrgId(0);
				roleInfo.setState(1);
				roleInfo.setRemark(roleName);
				roleInfo = save(roleInfo);
			}else{
				boolean changed = false;
				if (roleInfo.getOrgId()!=null&&roleInfo.getOrgId()>0){
					roleInfo.setOrgId(0);
					changed = true;
				}
				if(changed){
					update(roleInfo);
				}
			}
			
			// 检查及更新功能角色的权限配置
			updateRoleFunc(roleInfo, roleName, server, funcGroupMap, funcIdMap);
		}
		
		if(server.getAdminRole()!=null&&server.getAdminRole().length()>0){
			// 系统管理员拥有各功能模块管理员角色的相应功能权限
			RoleInfo adminRole = getRoleByName(ADMIN_ROLE_NAME);
			if (adminRole==null){
				adminRole=new RoleInfo();
				adminRole.setName(ADMIN_ROLE_NAME);
				adminRole.setRemark("拥有所有功能模块的管理员权限！");
				adminRole = save(adminRole);
			}
			updateRoleFunc(adminRole, server.getAdminRole(), server, funcGroupMap, funcIdMap);
		}
		
	}

	/**
	 * 级联删除指定功能权限及其权限范围
	 * @param funcId
	 */
	private void delFunc(Integer funcId) {
		FuncInfo example = new FuncInfo();
		example.setParentId(funcId);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		for(FuncInfo func:list){
			delFunc(func.getPkId());
		}
		// 删除所有引用的角色权限配置
		getRoleFuncDao().delByFuncId(funcId);
		try {
			getFuncInfoDao().delete(funcId);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 刷新已注册功能权限下的范围类型
	 * @param func 已注册的功能权限
	 * @param funcPurview 声明的功能权限
	 * @param funcIdMap
	 * @param funcCodeMap
	 * @throws Exception
	 */
	private void refreshFuncRangeType(FuncInfo func, Purview funcPurview, Map<Integer, FuncInfo> funcIdMap, Map<String, FuncInfo> funcCodeMap)
			throws Exception {

		// 准备可能需要删除的权限范围类型列表
		Map<Integer, FuncInfo> removeRangeTypeMap = new HashMap<Integer, FuncInfo>();
		// 加载已注册权限范围类型
		loadSubFuncs(func);
		// 添加为可能的待删除对象
		for(FuncInfo subFunc:func.getSubFuncs()){
			removeRangeTypeMap.put(subFunc.getPkId(), subFunc);
		}
		for(Purview rangeTypePurview:funcPurview.getPurviews()){
			FuncInfo rangeTypeFunc;
			if (rangeTypePurview.getPurviews().size()==0){
				// 简单范围, 添加一级范围类型,取名为默认范围列表
				rangeTypeFunc = getSubFuncByFuncCode(func, RIGHT_RANGE_DEFAULT_KEY);
				if (rangeTypeFunc==null){
					rangeTypeFunc = new FuncInfo();
					rangeTypeFunc.setName("权限范围");
					rangeTypeFunc.setParentId(func.getPkId());
					rangeTypeFunc.setFuncCode(RIGHT_RANGE_DEFAULT_KEY);
					rangeTypeFunc = funcInfoDao.save(rangeTypeFunc);
					rangeTypeFunc.setParent(func);
				}else{
					if(!rangeTypeFunc.getName().equals("权限范围")){
						rangeTypeFunc.setName("权限范围");
						rangeTypeFunc = funcInfoDao.update(rangeTypeFunc);
					}
				}
				refreshFuncRangeList(func, rangeTypeFunc, funcPurview, funcIdMap, funcCodeMap);
				if(removeRangeTypeMap.containsKey(rangeTypeFunc.getPkId())){
					removeRangeTypeMap.remove(rangeTypeFunc.getPkId());
				}
				// 简单范围, 未声明范围类型, 本级即范围列表, 结束范围类型循环
				break;
			}else{
				// 命名范围
				rangeTypeFunc = getSubFuncByFuncCode(func, rangeTypePurview.getPurviewKey());
				if (rangeTypeFunc==null){
					rangeTypeFunc = new FuncInfo();
					rangeTypeFunc.setName(rangeTypePurview.getName());
					rangeTypeFunc.setParentId(func.getPkId());
					rangeTypeFunc.setFuncCode(rangeTypePurview.getPurviewKey());
					rangeTypeFunc = funcInfoDao.save(rangeTypeFunc);
					rangeTypeFunc.setParent(func);
				}else{
					if(!rangeTypeFunc.getName().equals(rangeTypePurview.getName())){
						rangeTypeFunc.setName(rangeTypePurview.getName());
						rangeTypeFunc = funcInfoDao.update(rangeTypeFunc);
					}
				}
				refreshFuncRangeList(func, rangeTypeFunc, rangeTypePurview, funcIdMap, funcCodeMap);
				if(removeRangeTypeMap.containsKey(rangeTypeFunc.getPkId())){
					removeRangeTypeMap.remove(rangeTypeFunc.getPkId());
				}
			}
		}
		// 级联删除不需的角色权限注册
		for(Entry<Integer, FuncInfo> funcRangeType:removeRangeTypeMap.entrySet()){
			log.debug("将要删除权限范围类型："+funcRangeType.getValue().getName());
			delFunc(funcRangeType.getKey());
		}
		
	}

	/**
	 * 刷新范围列表项
	 * @param func					功能权限
	 * @param rangeTypeFunc			已注册范围类型(暗含待处理目标，范围列表项)
	 * @param rangeTypePurview		声明的范围类型，包含范围列表
	 * @param funcIdMap
	 * @param funcCodeMap
	 * @return
	 * @throws Exception
	 */
	private void refreshFuncRangeList(FuncInfo func, FuncInfo rangeTypeFunc, Purview rangeTypePurview, Map<Integer, FuncInfo> funcIdMap, Map<String, FuncInfo> funcCodeMap)
			throws Exception {
		
		if (rangeTypePurview.getPurviews().get(0).getPurviews().size()>0){
			// 多维的，现只支持二维

			// 准备可能需要删除的权限范围维度列表
			Map<Integer, FuncInfo> removeDimensionMap = new HashMap<Integer, FuncInfo>();
			loadSubFuncs(rangeTypeFunc);
			for(FuncInfo subFunc:rangeTypeFunc.getSubFuncs()){
				removeDimensionMap.put(subFunc.getPkId(), subFunc);
			}
			
			// 准备第一维度参数
			Purview rangeTypeColPurview = rangeTypePurview.getPurviews().get(0);
			// 获取或刷新第一维度标题项，即维度名称
			FuncInfo rangeTypeColFunc = refreshFuncRange(rangeTypeFunc, rangeTypeColPurview);
			if(removeDimensionMap.containsKey(rangeTypeColFunc.getPkId())){
				removeDimensionMap.remove(rangeTypeColFunc.getPkId());
			}
			
			// 准备第二维度参数
			Purview rangeTypeRowPurview = rangeTypePurview.getPurviews().get(1);
			// 获取或刷新第二维度标题项，即维度名称
			FuncInfo rangeTypeRowFunc = refreshFuncRange(rangeTypeFunc, rangeTypeRowPurview);
			if(removeDimensionMap.containsKey(rangeTypeRowFunc.getPkId())){
				removeDimensionMap.remove(rangeTypeRowFunc.getPkId());
			}
			
			// 级联删除不需要的维度注册
			for(Entry<Integer, FuncInfo> funcRange:removeDimensionMap.entrySet()){
				log.debug("将要删除功能权限："+funcRange.getValue().getName());
				delFunc(funcRange.getKey());
			}
			loadSubFuncs(rangeTypeFunc);
			
			// 准备刷新第一维度列表项
			// 准备可能需要删除的第一维度列表
			Map<Integer, FuncInfo> removeColMap = new HashMap<Integer, FuncInfo>();
			loadSubFuncs(rangeTypeColFunc);
			for(FuncInfo subFunc:rangeTypeColFunc.getSubFuncs()){
				removeColMap.put(subFunc.getPkId(), subFunc);
			}
			for(Purview rangePurview:rangeTypeColPurview.getPurviews()){
				FuncInfo rangeColFunc = refreshFuncRange(rangeTypeColFunc, rangePurview);
				if(removeColMap.containsKey(rangeColFunc.getPkId())){
					removeColMap.remove(rangeColFunc.getPkId());
				}
			}
			
			// 级联删除不需的二维列范围注册
			for(Entry<Integer, FuncInfo> funcRangeCol:removeColMap.entrySet()){
				delFunc(funcRangeCol.getKey());
			}
			loadSubFuncs(rangeTypeColFunc);
			
			// 准备可能需要删除的二维行范围列表
			Map<Integer, FuncInfo> removeRowMap = new HashMap<Integer, FuncInfo>();
			loadSubFuncs(rangeTypeRowFunc);
			for(FuncInfo subFunc:rangeTypeRowFunc.getSubFuncs()){
				removeRowMap.put(subFunc.getPkId(), subFunc);
			}
			for(Purview rangeRowPurview:rangeTypeRowPurview.getPurviews()){
				FuncInfo rangeRowFunc = refreshFuncRange(rangeTypeRowFunc, rangeRowPurview);
				if(removeRowMap.containsKey(rangeRowFunc.getPkId())){
					removeRowMap.remove(rangeRowFunc.getPkId());
				}
			}
			// 级联删除不需的角色权限注册
			for(Entry<Integer, FuncInfo> funcRangeRow:removeRowMap.entrySet()){
				log.debug("将要删除功能权限："+funcRangeRow.getValue().getName());
				delFunc(funcRangeRow.getKey());
			}
			loadSubFuncs(rangeTypeRowFunc);
			
			// 检查及更新行下列矩阵
			for(FuncInfo rangeRowFunc:rangeTypeRowFunc.getSubFuncs()){
				// 逐行清理行下列范围选项
				// 准备可能需要删除的行下列二维行范围列表
				Map<Integer, FuncInfo> removeMap = new HashMap<Integer, FuncInfo>();
				loadSubFuncs(rangeRowFunc);
				for(FuncInfo itemFunc:rangeRowFunc.getSubFuncs()){
					removeRowMap.put(itemFunc.getPkId(), itemFunc);
				}
				for(FuncInfo rangeColFunc:rangeTypeColFunc.getSubFuncs()){

					Purview rangePurview = new Purview();
					rangePurview.setName(rangeColFunc.getName()+"_"+rangeRowFunc.getName());
					rangePurview.setPurviewKey(rangeColFunc.getFuncCode()+"_"+rangeRowFunc.getFuncCode());

					FuncInfo rangeFunc = refreshFuncRange(rangeRowFunc, rangePurview);
					if(removeRowMap.containsKey(rangeFunc.getPkId())){
						removeRowMap.remove(rangeFunc.getPkId());
					}
					String funcRangeCode = func.getFuncCode()+":"+rangePurview.getPurviewKey();
					if (!funcCodeMap.containsKey(funcRangeCode)){
						funcCodeMap.put(funcRangeCode, rangeFunc);
					}
					if (!funcIdMap.containsKey(rangeTypeFunc.getPkId())){
						funcIdMap.put(rangeFunc.getPkId(), rangeFunc);
					}
				}
				// 级联删除不需的角色权限注册
				for(Entry<Integer, FuncInfo> funcRangeRow:removeRowMap.entrySet()){
					log.debug("将要删除功能权限："+funcRangeRow.getValue().getName());
					delFunc(funcRangeRow.getKey());
				}
				loadSubFuncs(rangeTypeRowFunc);
			}

			if(rangeTypeRowFunc.getSubFuncs().size()==0){
				delFunc(rangeTypeRowFunc.getPkId());
			}
		}else{
			// 一维的
			// 准备可能需要删除的权限范围项列表
			Map<Integer, FuncInfo> removeItemMap = new HashMap<Integer, FuncInfo>();
			loadSubFuncs(rangeTypeFunc);
			for(FuncInfo subFunc:rangeTypeFunc.getSubFuncs()){
				removeItemMap.put(subFunc.getPkId(), subFunc);
			}
			for(Purview rangePurview:rangeTypePurview.getPurviews()){

				FuncInfo rangeFunc = refreshFuncRange(rangeTypeFunc, rangePurview);
				if(removeItemMap.containsKey(rangeFunc.getPkId())){
					removeItemMap.remove(rangeFunc.getPkId());
				}
				String funcRangeCode = func.getFuncCode()+":"+rangePurview.getPurviewKey();
				if (!funcCodeMap.containsKey(funcRangeCode)){
					funcCodeMap.put(funcRangeCode, rangeFunc);
				}
				if (!funcIdMap.containsKey(rangeTypeFunc.getPkId())){
					funcIdMap.put(rangeFunc.getPkId(), rangeFunc);
				}
			}
			// 级联删除不需的角色权限注册
			for(Entry<Integer, FuncInfo> funcRange:removeItemMap.entrySet()){
				log.debug("将要删除功能权限："+funcRange.getValue().getName());
				delFunc(funcRange.getKey());
			}
			loadSubFuncs(rangeTypeFunc);
		}
	}

	/**
	 * 刷新权限范围项，无则添加，有则更新
	 * @param rangeTypeFunc
	 * @param rangePurview
	 * @return
	 * @throws Exception
	 */
	private FuncInfo refreshFuncRange(FuncInfo rangeTypeFunc, Purview rangePurview) throws Exception {
		FuncInfo rangeFunc = getSubFuncByFuncCode(rangeTypeFunc, rangePurview.getPurviewKey());
		if (rangeFunc==null){
			rangeFunc = new FuncInfo();
			rangeFunc.setName(rangePurview.getName());
			rangeFunc.setParentId(rangeTypeFunc.getPkId());
			rangeFunc.setFuncCode(rangePurview.getPurviewKey());
			rangeFunc = funcInfoDao.save(rangeFunc);
			rangeFunc.setParent(rangeTypeFunc);
		}else{
			if(!rangeFunc.getName().equals(rangePurview.getName())){
				rangeFunc.setName(rangePurview.getName());
				rangeFunc = funcInfoDao.update(rangeFunc);
			}
		}
		return rangeFunc;
	}

	/**
	 * 检查是否拥有角色管理权限
	 * @param currentUser
	 * @throws Exception
	 */
	private void checkManageRight(U currentUser) throws Exception {
		if (currentUser==null){
			throw new Exception("请先登录！");
		}
		if (!haveRight(RIGHT_ROLE_MANAGE, currentUser)){
			throw new Exception("你没有角色管理权限！");
		}
	}

	/**
	 * 检查是是否拥有指定角色的管理权限
	 * @param roleInfo
	 * @param currentUser
	 * @throws Exception
	 */
	@Override
	public boolean haveManageRight(RoleInfo roleInfo, U currentUser) {
		boolean result;
		
		if (currentUser==null){
			result = false;
		}else{
			try {
				checkRoleManageRange(roleInfo, currentUser);
				result = true;
			} catch (Exception e) {
				result = false;
			}
		}
		
		return result;
	}

	/**
	 * 检查是是否拥有指定角色的管理权限
	 * @param roleInfo
	 * @param currentUser
	 * @throws Exception
	 */
	@Override
	public boolean haveUserAuthRight(RoleInfo roleInfo, U currentUser) {
		boolean result;
		
		if (currentUser==null){
			result = false;
		}else{
			try {
				checkUserAuthRange(roleInfo, currentUser);
				result = true;
			} catch (Exception e) {
				result = false;
			}
		}
		
		return result;
	}

	/**
	 * 检查角色管理范围
	 * @param roleInfo
	 * @param currentUser
	 * @throws Exception
	 */
	private void checkRoleManageRange(RoleInfo roleInfo, U currentUser) throws Exception {
		if (currentUser==null){
			throw new Exception("请先登录！");
		}
		if (!haveRight(RIGHT_ROLE_MANAGE, currentUser)){
			throw new Exception("你没有角色管理权限！");
		}
		
		boolean result;
		if(currentUser.isSysAdmin()){
			result = true;
		}else{
			result = false;
			if(roleInfo.getOrgId()==null||roleInfo.getOrgId()==0){
				if(haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL)){
					result = true;
				}else{
					result = false;
				}
			}else{
				for(Object ud: currentUser.getUserDepts()){
					LocalDept userDept = (LocalDept) ud;
					if(roleInfo.getOrgId().equals(userDept.getOrgId())){
						result = true;
						break;
					}
				}
				if(!result){
					result = haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL);
				}
			}
						
		}
		if(!result){
			throw new Exception("该角色不在你的可管理范围之内！");
		}
		
	}

	/**
	 * 检查角色用户授权范围
	 * @param roleInfo
	 * @param currentUser
	 * @throws Exception
	 */
	private void checkUserAuthRange(RoleInfo roleInfo, U currentUser) throws Exception {
		if (currentUser==null){
			throw new Exception("请先登录！");
		}
		if (!haveRight(RIGHT_ROLE_MANAGE, currentUser)){
			throw new Exception("你没有角色管理权限！");
		}
		
		boolean result;
		if(currentUser.isSysAdmin()){
			result = true;
		}else{
			result = false;
			if(roleInfo.getOrgId()==null||roleInfo.getOrgId()==0){
				if(haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL)){
					result = true;
				}else{
					// 系统角色，即非组织机构角色，如果所包含的已授权权限没有超出自己可可管理权限的范围，则可以管理, 一票否决
					result = true;
					Set<Integer> roleFuncIds = getRoleFuncIds(roleInfo.getPkId());
					Set<Integer> managedFuncSet = getManagedFuncList(currentUser);
					for(Integer funcId:roleFuncIds){
						if(!managedFuncSet.contains(funcId)){
							result = false;
							break;
						}
					}
				}
			}else{
				for(Object ud: currentUser.getUserDepts()){
					LocalDept userDept = (LocalDept) ud;
					if(roleInfo.getOrgId().equals(userDept.getOrgId())){
						result = true;
						break;
					}
				}
				if(!result){
					result = haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL);
				}
			}
						
		}
		if(!result){
			throw new Exception("该角色不在你的可管理范围之内！");
		}
		
	}

	public RoleInfo getRoleByName(String roleName) {
		RoleInfo roleInfo = null;
		
		RoleInfo example = new RoleInfo();
		example.setName(roleName);
		example.setState(1);
		List<RoleInfo> list = baseDao.query(example);
		if (list!=null&&list.size()>0){
			roleInfo = list.get(0);
		}
	
		
		return roleInfo;
	}

	/**
	 * 获取角色记录
	 * @param index 当前页
	 * @param maxresult 每页数量 
	 * @param 
	 * @return
	 */	
	public QueryResult<RoleInfo> getRoleInfoAll(Integer index, Integer maxresult, String name, Integer orgId) {
		QueryResult<RoleInfo> result;
		if(orgId == null){
			result = getRoleInfoAll(null, name, index, maxresult);
		}else{
			List<Integer> orgIds = new ArrayList<Integer>();
			orgIds.add(orgId);
			result = getRoleInfoAll(orgIds, name, index, maxresult);
		}
		return result;
	}

	/**
	 * 获取角色记录
	 * @param index 当前页
	 * @param maxresult 每页数量 
	 * @param 
	 * @return
	 */	
	public QueryResult<RoleInfo> getRoleInfoAll(List<Integer> orgIds, String name, Integer index, Integer maxresult) {
		
		String whererjpql=" o.state=1";
		if(orgIds != null&&orgIds.size()>0){
			whererjpql += " and o.orgId in (";
			boolean first = true;
			for(Integer orgId:orgIds){
				if(first){
					first = false;
				}else{
					whererjpql += ",";
				}
				whererjpql += orgId;
			}
			whererjpql += ")";
		}
	    List<String> lst = new ArrayList<String>();
	    if (name != null && !name.trim().equals("")){
	        whererjpql = whererjpql + " and o.name  like ?";
	        lst.add("%"+name+"%");
	    }
	    LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
	    orderby.put("orgId","asc");
	    return baseDao.getScrollData(RoleInfo.class, "pkId", index, maxresult, whererjpql, lst.toArray(),orderby);
	}

	/**
	 * 获取所有权限
	 * @return
	 * @author 何杰 2013-1-31
	 */
	public List<RoleInfo> getAllRoleInfo() {
		return baseDao.queryAll();
	}
	
	/**
	 * 获取所有的角色信息
	 * @return
	 * @author 舒俊
	 */
	public List<RoleInfo> getRoleInfoAll(){
		RoleInfo role = new RoleInfo();
		role.setState(1);
		return baseDao.query(role);
	}

	/**
	 * 获取功能项信息
	 * @return
	 * @author 舒俊
	 */
	public LinkedHashMap<Map<String, Object>,List<Map<String, Object>>> getMenu(){
		LinkedHashMap<Map<String, Object>,List<Map<String, Object>>> lhp = new LinkedHashMap<Map<String, Object>,List<Map<String, Object>>>();

		// 遍历功能权限分组
		List<FuncInfo> funcGroupList = getSubFuncs(0);
		for(FuncInfo funcGroup : funcGroupList){
			Map<String, Object> mainItem = new HashMap<String, Object>();
			mainItem.put("pkId", funcGroup.getPkId());
			mainItem.put("name", funcGroup.getName());
			
			List<FuncInfo> funcList = getSubFuncs(funcGroup.getPkId());
			List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
			for(FuncInfo funcInfo:funcList){
				// 递归加载功能权限的范围范围
				loadSubFuncs(funcInfo, -1);

				// 递归构建功能权限基本属性及范围属性
				Map<String, Object> item = getFuncItem(funcInfo) ;
				
				list.add(item);
			}
			lhp.put(mainItem, list);
			
		}
		return lhp;
	}

	private void loadSubFuncs(FuncInfo funcInfo) {
		loadSubFuncs(funcInfo, 1);
	}

	private void loadSubFuncs(FuncInfo funcInfo, int depth) {
		List<FuncInfo> list = getSubFuncs(funcInfo.getPkId());
		funcInfo.setSubFuncs(list);
		for(FuncInfo subFunc:list){
			subFunc.setParent(funcInfo);
			if(depth==-1||depth>1){
				if(depth>1){
					depth--;
				}
				loadSubFuncs(subFunc, depth);
			}
		}
	}

	private List<FuncInfo> getSubFuncs(Integer parentId) {
		List<FuncInfo> list;
		
		FuncInfo example = new FuncInfo();
		example.setParentId(parentId);
		list = getFuncInfoDao().query(example);
		
		return list;
	}

	private Map<String, Object> getFuncItem(FuncInfo func) {
		Map<String, Object> item = new HashMap<String, Object>();

		item.put("pkId", func.getPkId());
		item.put("name", func.getName());
		
		if (func.getSubFuncs()!=null){
			List<Map<String, Object>> subFunclist = new ArrayList<Map<String,Object>>();
			for(FuncInfo subFunc:func.getSubFuncs()){
				Map<String, Object> subItem = getFuncItem(subFunc) ;
				subFunclist.add(subItem);
			}
			item.put("subFuncs", subFunclist);
		}
		
		return item;
	}

	@Override
	public QueryResult<RoleInfo> manage(Integer orgId, String name, String nowpage, String maxpage, U currentUser) throws Exception {
		QueryResult<RoleInfo> result = null;
		
		if(currentUser==null){
			throw new Exception("当前用户已失效，请重新登录！");
		}
		
		checkManageRight(currentUser);
		
		int page = 1;//当前页数
		int rowsPage = 100;//每页显示数
		if (nowpage != null && !nowpage.trim().equals("")) {
			page = Integer.parseInt(nowpage.trim());
			if(page==0){
				page=1;
			}
		}
		if (maxpage != null && !maxpage.trim().equals("")) {
			rowsPage = Integer.parseInt(maxpage.trim());
		}

		// 检查初始化条件
		
		// 根据权限范围，确定管理的角色的可见范围, 
		List<Integer> orgIds = null;
		
		if(!haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL)&&!haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_RANGE_ORG_ALL)){
			orgIds = new ArrayList<Integer>();
			if(orgId==null){
				orgIds.add(0);
			}
			Set<Integer> orgIdSet = new HashSet<Integer>();
			for(Object ud:currentUser.getUserDepts()){
				LocalDept userDept = (LocalDept) ud;
				if(userDept.getOrgId()!=null&&!orgIdSet.contains(userDept.getOrgId())){
					orgIds.add(userDept.getOrgId());
					orgIdSet.add(userDept.getOrgId());
				}
			}
		}else{
			if(orgId!=null){
				orgIds = new ArrayList<Integer>();
				orgIds.add(orgId);
			}
		}
		
		result = getRoleInfoAll(orgIds, name, page, rowsPage);
		Map<Integer, LocalDept> orgRootDeptMap = new HashMap<Integer, LocalDept>();
		for(RoleInfo roleInfo:result.getResultlist()){
			if(roleInfo.getOrgId()!=null&&roleInfo.getOrgId()>0){
				LocalDept orgRootDept;
				if(orgRootDeptMap.containsKey(roleInfo.getOrgId())){
					orgRootDept = orgRootDeptMap.get(roleInfo.getOrgId());
				}else{
					orgRootDept = getDeptInfoService().getRootDeptByOrgId(roleInfo.getOrgId());
					
					if (orgRootDept!=null){
						orgRootDeptMap.put(roleInfo.getOrgId(), orgRootDept);
					}
				}
				if(orgRootDept!=null){
					roleInfo.setOrgName(orgRootDept.getName());
				}
			}
		}
		
		return result;
	}

	public RoleInfo edit(Integer roleId, U currentUser) throws Exception {
		checkManageRight(currentUser);
		
		RoleInfo roleInfo = getById(roleId);
		if(roleInfo==null||roleInfo.getState()!=null&&roleInfo.getState()!=1){
			throw new Exception("要编辑的角色不存在或已删除！");
		}
		
		checkUserAuthRange(roleInfo, currentUser);
		
		return roleInfo;
	}

	public RoleInfo save(RoleInfo roleVo, U currentUser) throws Exception {
		checkManageRight(currentUser);
		
		checkUserAuthRange(roleVo, currentUser);
		RoleInfo rolePo;
		if(roleVo.getPkId()!=null) {
			rolePo = getById(roleVo.getPkId());
			rolePo.setName(roleVo.getName());
			rolePo.setRemark(roleVo.getRemark());
		}else {
			rolePo = roleVo;
		}
		if (roleVo.getOrgId()==null){
			roleVo.setOrgId(0);
		}
		if (roleVo.getState()==null){
			roleVo.setState(1);
		}
		if(roleVo.getPkId()!=null) {
			rolePo = super.update(rolePo);
		}else {
			rolePo = super.save(rolePo);
		}
		return rolePo;
	}

	public boolean delete(Integer roleId, U currentUser) throws Exception {
		checkManageRight(currentUser);
		
		RoleInfo rolePo = baseDao.getById(roleId);
		if (rolePo!=null){
			if ((rolePo.getOrgId()==null||rolePo.getOrgId()<=0)&&isFuncRole(rolePo)){
				throw new Exception("不能删除系统业务角色");
			}
			
			checkUserAuthRange(rolePo, currentUser);
			
			// 清除角色授权用户列表
			getUserRoleService().cleanRoleUsersByRoleId(roleId);
			// 删除角色权限配置
			clearRoleFunc(roleId);
			// 删除角色
			return super.delete(rolePo);
		}else{
			throw new Exception("要删除的角色并不存在");
		}
	}

	/**
	 * 是否是系统业务角色
	 * @param rolePo
	 * @return
	 */
	public boolean isFuncRole(RoleInfo rolePo) {
		boolean result = false;
		
		// 系统管理员拥有各功能模块管理员角色的相应功能权限
		RoleInfo adminRole = getRoleByName(ADMIN_ROLE_NAME);
		if(adminRole!=null&&adminRole.getPkId().equals(rolePo.getPkId())){
			result = false;
			return result;
		}

		// 遍历所有提供了功能角色及权限代码声明接口的功能模块
		for(Entry<String, IHaveRoleFuncs> serverEntry:AllContext.getAppContext().getBeansOfType(IHaveRoleFuncs.class).entrySet()){
			String serverName = serverEntry.getKey();
			IHaveRoleFuncs server = serverEntry.getValue();

			log.info("检查 "+serverName+" 的角色权限配置");
			
			// 检查及更新功能模块下的各功能角色及其权限配置
			for (String roleName: server.getRoleList()){
				// 检查及更新功能角色
				RoleInfo roleInfo = getRoleByName(roleName);
				if (roleInfo!=null&&roleInfo.getPkId().equals(rolePo.getPkId())){
					result = true;
					break;
				}
			}
			if(result){
				break;
			}
		}
		
		return result;
	}

	/**
	 * 更新角色权限
	 * @param roleInfo
	 * @param roleName
	 * @param server
	 * @param funcCodeMap
	 * @param funcIdMap
	 * @throws Exception
	 */
	private void updateRoleFunc(RoleInfo roleInfo, String roleName, IHaveRoleFuncs server, Map<String, Map<String, FuncInfo>> funcGroupMap, Map<Integer, FuncInfo> funcIdMap) throws Exception {

		// 检查服务模块的角色权限声明
		if(server.getRoleFuncs().containsKey(roleName)){
			Map<Integer, FuncInfo> roleFuncs = new HashMap<Integer, FuncInfo>();
			
			// 服务声明的功能权限分组，避免权限代码与其他功能模块的冲突
			Set<String> funcGroup = new HashSet<String>();
			for(Purview purview : server.getFuncGroup()){
				funcGroup.add(purview.getName());
			}
			for(String funcKey:server.getRoleFuncs().get(roleName)){
				FuncInfo funcInfo = null;
				String rangeList = null;
				String[] ranges = null;
				// 分离权限范围声明
				if(funcKey.contains("(")){
					rangeList = funcKey.substring(funcKey.indexOf("(")+1);
					if(rangeList.contains(")")){
						rangeList = rangeList.substring(0, rangeList.indexOf(")"));
					}
					funcKey = funcKey.substring(0, funcKey.indexOf("("));
				}
				if (rangeList!=null){
					ranges = rangeList.split(",");
				}
				
				// 权限声明是否全局代码
				String groupName;
				String code;
				Map<String, FuncInfo> funcCodeMap=null;
				if(funcKey.contains(".")){
					// 是全局代码
					groupName = funcKey.substring(0, funcKey.indexOf("."));
					code = funcKey.substring(funcKey.indexOf("."));
					
				}else{
					groupName = null;
					code = funcKey;
				}
				if (groupName==null){
					// 非全局代码
					for(Map<String, FuncInfo> groupItemMap:funcGroupMap.values()){
						funcInfo = groupItemMap.get(funcKey);
						if(funcInfo!=null){
							funcCodeMap = groupItemMap;
							break;
						}
					}
				}else{
					funcCodeMap = funcGroupMap.get(groupName);
					funcInfo = funcCodeMap.get(code);
				}
				// 可能有些权限并未注册使用
				if(funcInfo!=null){
					roleFuncs.put(funcInfo.getPkId(), funcInfo);
					// 检查范围配置
					if (ranges!=null){
						for(String range:ranges){
							funcInfo = funcCodeMap.get(funcKey+":"+range);
							if (funcInfo!=null){
								roleFuncs.put(funcInfo.getPkId(), funcInfo);
							}
						}
					}
				}
			}
			
			// 关闭原有角色权限配置中不再配置的授权项目
			for(RoleFunc roleFunc:getRoleFuncList(roleInfo.getPkId())){
				// 查找角色配置的权限对象
				FuncInfo func = null;
				if (roleFuncs.containsKey(roleFunc.getFuncId())){
					func = roleFuncs.get(roleFunc.getFuncId());
				}
				if (func!=null){
					if(funcIdMap.containsKey(func.getPkId())&&!roleFuncs.containsKey(func.getPkId())){
						roleFunc.setState(2);
						getRoleFuncDao().update(roleFunc);
						getRoleFuncDao().delete(roleFunc);
					}
				}
			}
			
			// 重新更新角色权限配置
			for(FuncInfo funcInfo:roleFuncs.values()){
				addFuncForRoleId(funcInfo.getPkId(), roleInfo.getPkId());
			}
		}else{
			log.debug("不存在！"+roleName);
		}
	}

	private FuncInfo loadFuncInfo(Integer funcId) {
		FuncInfo funcInfo = null;
		
		if(funcMap==null){
			funcMap = new HashMap<Integer, FuncInfo>();
		}
		
		if(funcPathMap==null){
			funcPathMap = new HashMap<String, FuncInfo>();
		}
		
		if(funcId!=null){
			if(funcMap.containsKey(funcId)){
				funcInfo = funcMap.get(funcId);
			}else{
				funcInfo = getFuncInfoDao().getById(funcId);
				if(funcInfo!=null){
					loadParents(funcInfo, funcMap);
					funcMap.put(funcId, funcInfo);
					funcPathMap.put(funcInfo.getPath(), funcInfo);
					loadSubFuncs(funcInfo, funcMap);
				}
			}
		}
		
		return funcInfo;
	}

	@Override
	public boolean isAdminRole(RoleInfo roleInfo) {
		boolean result = false;
		if(roleInfo!=null){
			result = roleInfo.getName().equals(ADMIN_ROLE_NAME)&&(roleInfo.getOrgId()==null||roleInfo.getOrgId()==0);
		}
		return result;
	}

	@Override
	public boolean haveRight(String funcCode, @SuppressWarnings("rawtypes") LocalUser currentUser) throws Exception {
		boolean result = false;
		
		if(currentUser!=null){
			if (currentUser.isSuperAdmin()){
				result = true;
			}else if (currentUser.isSysAdmin()){
				result = !RIGHT_SYS_MANAGE.endsWith(funcCode);
			}else{
				FuncInfo sysManageFunc = null;
				FuncInfo sysFunc = getMainFuncInfoByName("系统管理");
				if(sysFunc!=null){
					sysManageFunc = getFuncInfoByRangeCode(sysFunc, RIGHT_SYS_MANAGE);
				}
				// 要求调用前已加载用户角色列表
				if(currentUser.getRoles()==null){
					loadUserRoles((U) currentUser);
					Set<Integer> userFuncSet = new HashSet<Integer>(); 
					for(Object role: currentUser.getRoles()){
						RoleInfo userRole = (RoleInfo) role;
						
						RoleFunc example = new RoleFunc();
						example.setRoleId(userRole.getPkId());
						example.setState(1);
						for(RoleFunc roleFunc:getRoleFuncDao().query(example)){
							if(userRole.getName().equals(ADMIN_ROLE_NAME)&&sysManageFunc!=null&&sysManageFunc.getPkId().equals(roleFunc.getFuncId())){
								
							}else{
								userFuncSet.add(roleFunc.getFuncId());
							}
						}
					}
					
					// 获取 权限Key对应的权限实体，
					List<FuncInfo> funcs = getFuncInfoByFuncCode(funcCode);
					for(FuncInfo func:funcs){
						if (userFuncSet.contains(func.getPkId())){
							result = true;
							break;
						}
					}
					if(!result){
						// 没有权限，看是否拥有系统管理员权限
						funcs = getFuncInfoByFuncCode(RIGHT_ROLE_MANAGE);
						for(FuncInfo func:funcs){
							if (userFuncSet.contains(func.getPkId())&&haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_ROLE_MODULE_USER, RIGHT_RANGE_ORG_ALL)){
								result = true;
								break;
							}
						}
					}
				}else{
					for(Object role: currentUser.getRoles()){
						RoleInfo userRole = (RoleInfo) role;
						if(isAdminRole(userRole)){
							result = !RIGHT_SYS_MANAGE.endsWith(funcCode);;
							break;
						}
						// 遍历角色所拥有的权限中是否有指定的权限
						if (userRole.getRoleFuncMap()==null){
							// 还未为加载角色权限，先加载角色权限
							Map<String, Set<FuncInfo>> roleFuncMap = new HashMap<String, Set<FuncInfo>>();
							for(RoleFunc roleFunc:getRoleFuncList(userRole.getPkId())){
								FuncInfo funcInfo = loadFuncInfo(roleFunc.getFuncId());
								if(funcInfo.isFuncInfo()){
									Set<FuncInfo> funcSet;
									if(roleFuncMap.containsKey(funcInfo.getFuncCode())){
										funcSet = roleFuncMap.get(funcInfo.getFuncCode());
									}else{
										funcSet = new HashSet<FuncInfo>();
										roleFuncMap.put(funcInfo.getFuncCode(), funcSet);
									}
									funcSet.add(funcInfo);
								}
							}
							
							userRole.setRoleFuncMap(roleFuncMap);
						}else{
							
						}
						if(userRole.getRoleFuncMap().containsKey(funcCode)){
							result = true;
							break;
						}
					}
				}
			}
		}
		
		return result;
	}
	
	/**
	 * 是否拥有指定功能权限下指定范围的授权，指定范围表示不限，即有一个就算有，主要针对二维权限
	 */
	@Override
	public boolean haveRightRange(LocalUser currentUser, String funcCode, String... rangeCodes) {
		boolean range = false;
		
		if(currentUser!=null){
			if (currentUser.isSuperAdmin()){
				range = true;
			}else if (currentUser.isSysAdmin()){
				range = !RIGHT_SYS_MANAGE.equals(funcCode);
			}else{
				Set<Integer> userFuncSet = new HashSet<Integer>();
				for(Object role:currentUser.getRoles()){
					RoleInfo roleInfo = (RoleInfo) role;
					for(Integer funcId:getRoleFuncIds(roleInfo.getPkId())){
						userFuncSet.add(funcId);
					}
				}
				
				// 获取 权限Key对应的权限实体，
				List<FuncInfo> funcs;
				if(funcMap==null){
					funcs = getFuncInfoByFuncCode(funcCode);
				}else{
					funcs = new ArrayList<FuncInfo>();
					for(FuncInfo func:funcMap.values()){
						if (func.getFuncCode().equals(funcCode)&&func.isFuncInfo()){
							funcs.add(func);
						}
					}
					funcs = getFuncInfoByFuncCode(funcCode);
				}
				
				for(FuncInfo func:funcs){
					// 获取指定功能权限下最终的范围授权对象列表，只要有一个授权即算有权限
					List<FuncInfo> rangeList = getRangeTypeByRangeCode(func, rangeCodes);
					if(rangeList!=null&&rangeList.size()>0){
						range = false;
						for(FuncInfo rangeFunc:rangeList){
							if(userFuncSet.contains(rangeFunc.getPkId())){
								range = true;
								break;
							}
						}
						if (range){
							break;
						}
					}
				}
			}
		}
		
		return range;
	}

	/**
	 * 获取指定功能权限下最终的范围授权对象列表，其中二维范围需要连续的两个范围代码来确定一个授权范围对象，参数不足时，表示不限
	 * @param func
	 * @param rangeCodes
	 * @return
	 */
	private List<FuncInfo> getRangeTypeByRangeCode(FuncInfo func, String[] rangeCodes) {
		List<FuncInfo> rangeFuncList = new ArrayList<FuncInfo>();
		
		loadSubFuncs(func, -1);
		for(int i=0;i<rangeCodes.length;i++){
			String rangeCode = rangeCodes[i];
			boolean complate = false;
			
			// 根据权限范围代码查找有效权限范围对象，
			// 二维权限需要连续的两个范围代码才能确定一个有效的权限范围对象
			for(FuncInfo funcType:func.getSubFuncs()){
				// 在一致具体的范围类型下，每个参数确定一个维度
				if(funcType.getSubFuncs().size()==2&&funcType.getSubFuncs().get(0).getSubFuncs().size()>0&&funcType.getSubFuncs().get(1).getSubFuncs().size()>0){
					// 是一个二维范围,有效范围目标在第二维范围名下，但两个维度的顺序不确定
					FuncInfo colRange = null;
					FuncInfo rowRange = null;
					for(FuncInfo rFunc:funcType.getSubFuncs().get(0).getSubFuncs()){
						if (rangeCode.equals(rFunc.getFuncCode())||i<rangeCodes.length-1&&rangeCodes[i+1].equals(rFunc.getFuncCode())){
							if(rFunc.getSubFuncs().size()>0){
								rowRange = rFunc;
							}else{
								colRange = rFunc;
							}
							break;
						}
					}
					for(FuncInfo rFunc:funcType.getSubFuncs().get(1).getSubFuncs()){
						if (rangeCode.equals(rFunc.getFuncCode())||i<rangeCodes.length-1&&rangeCodes[i+1].equals(rFunc.getFuncCode())){
							if(rFunc.getSubFuncs().size()>0){
								rowRange = rFunc;
							}else{
								colRange = rFunc;
							}
							break;
						}
					}
					if (colRange!=null&&rowRange!=null){
						// 行、列都已确定，有唯一对象被获取
						String code = colRange.getFuncCode()+"_"+rowRange.getFuncCode();
						for(FuncInfo cRange:rowRange.getSubFuncs()){
							if(code.equals(cRange.getFuncCode())){
								rangeFuncList.add(cRange);
								complate = true;
								break;
							}
						}
						if (complate){
							i++;	// 多处理了一个参数
							break;
						}
					}else if (colRange==null&&rowRange==null){
						// 行、列都未确定，不限，全部添加
						for(FuncInfo rowFunc:funcType.getSubFuncs().get(1).getSubFuncs()){
							for(FuncInfo rFunc:rowFunc.getSubFuncs()){
								rangeFuncList.add(rFunc);
							}
							// 一行的所有列
						}
						// 所有的行
						complate = true;
						i++;	// 多处理了一个参数
						break;
					}else if(rowRange!=null){
						// 行确定了，列不确定，不限列
						for(FuncInfo rFunc:rowRange.getSubFuncs()){
							rangeFuncList.add(rFunc);
						}
						// 一行的所有列
						complate = true;
						i++;	// 多处理了一个参数
						break;
					}else{
						// 列确定了，行不确定，添加所有行的指定列
						for(FuncInfo rowFunc:funcType.getSubFuncs().get(1).getSubFuncs()){
							String code = colRange.getFuncCode()+"_"+rowFunc.getFuncCode();
							for(FuncInfo cRange:rowFunc.getSubFuncs()){
								if(code.equals(cRange.getFuncCode())){
									rangeFuncList.add(cRange);
									break;
								}
							}
							// 一行的指定列
						}
						// 所有行的指定列完成
						complate = true;
						i++;	// 多处理了一个参数
						break;
					}
				}else{
					// 是一个一维范围
					for(FuncInfo rFunc:funcType.getSubFuncs()){
						if (rangeCode.equals(rFunc.getFuncCode())){
							rangeFuncList.add(rFunc);
							complate = true;
							break;
						}
					}
				}
				if(complate){
					break;
				}
			}
		}
		
		return rangeFuncList;
	}

	private List<FuncInfo> getFuncInfoByFuncCode(String funcCode) {
		List<FuncInfo> funcs = new ArrayList<FuncInfo>();
		
		FuncInfo example = new FuncInfo();
		example.setFuncCode(funcCode);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		for(FuncInfo funcInfo:list){
			funcs.add(funcInfo);
		}	
		
		return funcs;
	}

	private FuncInfo getMainFuncInfoByName(String name) {
		FuncInfo mainFunc = null;
		
		FuncInfo example = new FuncInfo();
		example.setName(name);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		for(FuncInfo func:list){
			if(func.getParentId()==null||func.getParentId().intValue()==0){
				mainFunc = func;
				break;
			}

		}
		
		return mainFunc;
	}

	private FuncInfo getMainFuncInfoByCode(String funcCode) {
		FuncInfo mainFunc = null;
		
		FuncInfo example = new FuncInfo();
		example.setFuncCode(funcCode);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		for(FuncInfo func:list){
			if(func.getParentId()==null||func.getParentId().intValue()==0){
				mainFunc = func;
				break;
			}

		}
		
		return mainFunc;
	}

	private FuncInfo getFuncInfoByRangeCode(FuncInfo mainFunc, String funcCode) {
		FuncInfo funcInfo = null;
		
		FuncInfo example = new FuncInfo();
		example.setParentId(mainFunc.getPkId());
		example.setFuncCode(funcCode);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		if(list!=null&&list.size()>0){
			funcInfo = list.get(0);
		}
		
		return funcInfo;
	}
	
	private void loadSubFuncs(FuncInfo funcInfo, Map<Integer, FuncInfo> funcMap) {
		if (funcMap==null){
			funcMap = new HashMap<Integer, FuncInfo>();
		}
		List<FuncInfo> subFuncs = new ArrayList<FuncInfo>();
		for(FuncInfo subFunc:getSubFuncs(funcInfo.getPkId())){
			if (funcMap.containsKey(subFunc.getPkId())){
				subFunc = funcMap.get(subFunc.getPkId());
				subFunc.setParent(funcInfo);
			}else{
				subFunc.setParent(funcInfo);
				funcMap.put(subFunc.getPkId(), subFunc);
				loadSubFuncs(subFunc, funcMap);
			}
			subFuncs.add(subFunc);
		}
		funcInfo.setSubFuncs(subFuncs);
	}

	private void loadParents(FuncInfo funcInfo, Map<Integer, FuncInfo> funcMap) {
		if (funcInfo.getParentId()!=null&&funcInfo.getParentId()>0&&funcInfo.getParent()==null){
			FuncInfo parent;
			if (funcMap.containsKey(funcInfo.getParentId())){
				parent = funcMap.get(funcInfo.getParentId());
			}else{
				parent = getFuncInfoDao().getById(funcInfo.getParentId());
				funcMap.put(parent.getPkId(), parent);
			}
			funcInfo.setParent(parent);
			if (parent.getParentId()!=null&&parent.getParentId()>0&&parent.getParent()==null){
				loadParents(parent, funcMap);
			}
		}else{
			if(rootMap==null){
				rootMap = new HashMap<Integer, FuncInfo>();
			}
			if(!rootMap.containsKey(funcInfo.getPkId())){
				rootMap.put(funcInfo.getPkId(), funcInfo);
			}
		}
	}

	/**
	 * 获取用户可管理的功能项，自己不一定拥有
	 * @return
	 * @author 舒俊
	 */
	public String getManagedFuncArray(RoleInfo roleInfo, U currentUser){
		String result = null;

		if(haveManageRight(roleInfo, currentUser)){
			Set<Integer> funcSet = getManagedFuncList(currentUser);
			for(Integer funcId:funcSet){
				if(result==null){
					result = ""+funcId;
				}else{
					result += ","+funcId;
				}
			}
		}else{
			result = "";
		}
		
		return result;
	}

	/**
	 * 获取用户可管理的功能项，自己不一定拥有
	 * @return
	 * @author 舒俊
	 */
	private Set<Integer> getManagedFuncList(U currentUser) {
		// 自己拥有的权限
		Set<Integer> funcSet = getUserFuncList(currentUser);
		
		// 再根据角色权限管理范确定其他可管理权限
		try {
			if(haveRight(RIGHT_ROLE_MANAGE, currentUser)){
				for(FuncInfo funcGroup:getFuncGroupList()){
					if(!funcGroup.getName().equals("系统管理")){
						// 系统管理组外的权限，根据权限范围进行范围缩减
						loadSubFuncs(funcGroup, -1);
						for(FuncInfo funcInfo:funcGroup.getSubFuncs()){
							addFunc(funcSet, funcInfo, currentUser);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return funcSet;
	}

	/**
	 * 获取用户拥有的功能项
	 * @return
	 * @author Lzyyj
	 */
	private Set<Integer> getUserFuncList(U currentUser) {
		// 自己拥有的权限
		Set<Integer> funcSet = new HashSet<Integer>();
		if(currentUser.isSysAdmin()){
			RoleInfo roleInfo = getRoleByName(ADMIN_ROLE_NAME);
			List<RoleFunc> roleFuncArr = getRoleFuncList(roleInfo.getPkId());
			for(int i=0;i<roleFuncArr.size();i++){
				Integer funcId = roleFuncArr.get(i).getFuncId();
				if(!funcSet.contains(funcId)){
					funcSet.add(funcId);
				}
			}
		}else{
			for(Object role:currentUser.getRoles()){
				RoleInfo roleInfo = (RoleInfo) role;
				List<RoleFunc> roleFuncArr = getRoleFuncList(roleInfo.getPkId());
				for(int i=0;i<roleFuncArr.size();i++){
					Integer funcId = roleFuncArr.get(i).getFuncId();
					if(!funcSet.contains(funcId)){
						funcSet.add(funcId);
					}
				}
			}
		}
		
		return funcSet;
	}

	/**
	 * 添加功能权及其范围, 范围不超出角色权限管理中指定的范围
	 * @param funcSet
	 * @param funcInfo
	 */
	private void addFunc(Set<Integer> funcSet, FuncInfo funcInfo, U currentUser) {
		// 添加功能权
		if(!funcSet.contains(funcInfo.getPkId())){
			funcSet.add(funcInfo.getPkId());
		}
		
		if(funcInfo.getSubFuncs().size()>0){
			if(funcInfo.getSubFuncs().get(0).getSubFuncs().size()==0){
				// 下级无内容，简单范围
				for(FuncInfo rangeType:funcInfo.getSubFuncs()){
					addFuncRangeType(funcSet, rangeType, currentUser);
				}
			}else{
				// 有命名范围，添加权限下的各种类型的范围
				addFuncRangeTypes(funcSet, funcInfo, currentUser);
			}
		}
	}

	private void addFuncRangeTypes(Set<Integer> funcSet, FuncInfo funcInfo, U currentUser){
		for(FuncInfo rangeType:funcInfo.getSubFuncs()){
			addFuncRangeType(funcSet, rangeType, currentUser);
		}
	}

	/**
	 * 添加权限范围类型下的具体范围项
	 * @param funcSet
	 * @param rangeType
	 */
	private void addFuncRangeType(Set<Integer> funcSet, FuncInfo rangeType, U currentUser) {
		boolean twoDimensional = true;
		FuncInfo colRangeType = null;
		FuncInfo rowRangeType = null;
		// 区分一维范及二维范围
		if(rangeType.getSubFuncs().size()>=2){
			// 假定为二维
			for(FuncInfo dimensionType:rangeType.getSubFuncs()){
				if(dimensionType.getSubFuncs().size()>0&&dimensionType.getSubFuncs().get(0).getSubFuncs().size()>0){
					if(rowRangeType==null){
						rowRangeType = dimensionType;
					}else{
						twoDimensional = false;
						break;
					}
				}else{
					if(colRangeType==null){
						colRangeType = dimensionType;
					}else{
						twoDimensional = false;
						break;
					}
				}
			}
			if(colRangeType==null||rowRangeType==null){
				twoDimensional = false;
			}
		}else{
			twoDimensional = false;
		}
		
		if(twoDimensional){
			// 二维范围处理
			// 行范围类型，先看名称是否是组织机构类型，再看项目是否是组织机构类型
			boolean rowIsOrgRange = rowRangeType.getName().equalsIgnoreCase("组织机构范围");		// 是否是组织机构范围
			if(!rowIsOrgRange){
				for(FuncInfo rangeItem:rowRangeType.getSubFuncs()){
					if(rangeItem.getName().indexOf("所属部门")>=0||rangeItem.getName().indexOf("所属组织机构")>0){
						rowIsOrgRange = true;
						break;
					}
				}
			}
			// 行范围类型，先看名称是否是组织机构类型，再看项目是否是组织机构类型
			boolean colIsOrgRange = colRangeType.getName().equalsIgnoreCase("组织机构范围");		// 是否是组织机构范围
			if(!colIsOrgRange){
				for(FuncInfo rangeItem:colRangeType.getSubFuncs()){
					if(rangeItem.getName().indexOf("所属部门")>=0||rangeItem.getName().indexOf("所属组织机构")>0){
						colIsOrgRange = true;
						break;
					}
				}
			}
			for(FuncInfo rowRangeItem:rowRangeType.getSubFuncs()){
				if(rowIsOrgRange){
					// 行类型是组织机构范围，选择添加
					if(haveRightRange(currentUser, RIGHT_ROLE_MANAGE, rowRangeItem.getFuncCode())){
						for(FuncInfo rangeItem:rowRangeItem.getSubFuncs()){
							if(!funcSet.contains(rangeItem.getPkId())){
								funcSet.add(rangeItem.getPkId());
							}
						}
					}
				}else{
					// 非组织机构范围，全部添加
					for(FuncInfo rowColRangeItem:rowRangeItem.getSubFuncs()){
						String rowColFuncCode = rowColRangeItem.getFuncCode().split("_")[0];
						if(haveRightRange(currentUser, RIGHT_ROLE_MANAGE, rowColFuncCode)){
							if(!funcSet.contains(rowColRangeItem.getPkId())){
								funcSet.add(rowColRangeItem.getPkId());
							}
						}
					}
				}
				
				
			}
			for(FuncInfo colRangeItem:colRangeType.getSubFuncs()){
				if (colRangeItem.getSubFuncs().size()==0){
					// 下级无内容，简单范围
					// 如果是组织机构范围，现在在可管理范围之内
					if(!funcSet.contains(colRangeItem.getPkId())){
						funcSet.add(colRangeItem.getPkId());
					}
					addFunc(funcSet, colRangeItem, currentUser);
					break;
				}else{
					// 命名范围
					addFunc(funcSet, colRangeItem, currentUser);
				}
			}
		}else{
			// 一维范围处理
			if(!funcSet.contains(rangeType.getPkId())){
				funcSet.add(rangeType.getPkId());
			}
			boolean isOrgRange = rangeType.getName().equalsIgnoreCase("组织机构范围");		// 是否是组织机构范围
			if(!isOrgRange){
				for(FuncInfo rangeItem:rangeType.getSubFuncs()){
					if(rangeItem.getName().indexOf("所属部门")>=0||rangeItem.getName().indexOf("所属组织机构")>0){
						isOrgRange = true;
						break;
					}
				}
			}
			if(isOrgRange){
				// 组织机构范围，选择添加
				for(FuncInfo rangeItem:rangeType.getSubFuncs()){
					if(!funcSet.contains(rangeItem.getPkId())){
						funcSet.add(rangeItem.getPkId());
					}
				}
			}else{
				// 非组织机构范围，全部添加
				for(FuncInfo rangeItem:rangeType.getSubFuncs()){
					if(!funcSet.contains(rangeItem.getPkId())){
						funcSet.add(rangeItem.getPkId());
					}
				}
			}
		}
	}

	private void addRangeItem(Set<Integer> funcSet, FuncInfo funcInfo, U currentUser) {
		for(FuncInfo rangeType:funcInfo.getSubFuncs()){
			if(!funcSet.contains(rangeType.getPkId())){
				funcSet.add(rangeType.getPkId());
			}
			addFunc(funcSet, rangeType, currentUser);
		}
	}

	/**
	 * 获取用户拥有的功能项
	 * @return
	 * @author 舒俊
	 */
	public String getUserFuncArray(U currentUser){
		String result = null;
		
		Set<Integer> funcSet = getUserFuncList(currentUser);
		for(Integer funcId:funcSet){
			if(result==null){
				result = ""+funcId;
			}else{
				result += ","+funcId;
			}
		}
		
		return result;
	}

	/**
	 * 获取角色功能项
	 * @return
	 * @author 舒俊
	 */
	@Override
	public String getRoleFuncArray(int roleId){
		String result = null;
		
		List<RoleFunc> roleFuncArr = getRoleFuncList(roleId);
		for(int i=0;i<roleFuncArr.size();i++){
			if(result==null){
				result = ""+roleFuncArr.get(i).getFuncId();
			}else{
				result += ","+roleFuncArr.get(i).getFuncId();
			}
		}
		
		return result;
	}

	private Set<Integer> getRoleFuncIds(int roleId) {
		Set<Integer> funcIds = new HashSet<Integer>();
		
		List<RoleFunc> roleFuncArr = getRoleFuncList(roleId);
		for(RoleFunc roleFunc:roleFuncArr){
			if(!funcIds.contains(roleFunc.getFuncId())){
				funcIds.add(roleFunc.getFuncId());
			}
		}
		return funcIds;
	}

	/**
	 * 获取角色功能项
	 * @return
	 * @author 舒俊
	 */
	public List<RoleFunc> getRoleFuncList(int roleId) {
		RoleFunc roleFunc = new RoleFunc();
		roleFunc.setRoleId(roleId);
		roleFunc.setState(1);
		List<RoleFunc> roleFuncArr = getRoleFuncDao().query(roleFunc);
		return roleFuncArr;
	}

	public void addFuncForRoleId(Integer funcId, Integer roleId) {
		RoleFunc roleFunc = new RoleFunc();
		roleFunc.setRoleId(roleId);
		roleFunc.setFuncId(funcId);
		List<RoleFunc> list = getRoleFuncDao().query(roleFunc);
		if (list!=null&&list.size()>0){
			roleFunc = list.get(0);
			roleFunc.setState(1);
			getRoleFuncDao().update(roleFunc);
		}else{
			roleFunc.setState(1);
			getRoleFuncDao().save(roleFunc);
		}
		
	}

	public RoleFunc getRoleFunc(Integer roleId, Integer funcId) {
		RoleFunc roleFunc = null;
		
		RoleFunc example = new RoleFunc();
		example.setRoleId(roleId);
		example.setFuncId(funcId);
		List<RoleFunc> list = getRoleFuncDao().query(example);
		if (list!=null&&list.size()>0){
			roleFunc = list.get(0);
		}
		
		return roleFunc;
	}

	@Override
	public List<LocalDept> getManageOrgList(LocalUser currentUser) throws Exception {
		List<LocalDept> list;
		
		Map<Integer, LocalDept> managedOrgs = getManagedOrgs(currentUser);
		if(managedOrgs==null){
			list = getDeptInfoService().getOrgRootDeptList();
		}else{
			list = new ArrayList<LocalDept>();
			
			for(LocalDept deptInfo:managedOrgs.values()){
				list.add(deptInfo);
			}
		}
		
		return list;
	}

	@Override
	public Map<Integer, LocalDept> getManagedOrgs(LocalUser currentUser) throws Exception {
		Map<Integer, LocalDept> deptMap;
		if(haveRight(RIGHT_ROLE_MANAGE, currentUser)&&haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_ROLE_MODULE_USER, RIGHT_RANGE_ORG_ALL)){
			deptMap = null;
		}else{
			deptMap = new HashMap<Integer, LocalDept>();
			if (haveRight(RIGHT_ROLE_MANAGE, currentUser)&&haveRightRange(currentUser, RIGHT_ROLE_MANAGE, RIGHT_ROLE_MODULE_USER, RIGHT_RANGE_ORG_ORG)){
				for(Object ud:currentUser.getUserDepts()){
					LocalDept userDept = (LocalDept) ud;
					LocalDept orgRootDept = userDept.getOrgRootDept();
					if(orgRootDept!=null&&orgRootDept.getPkId()!=null&&orgRootDept.getPkId().intValue()>0&&!deptMap.containsKey(orgRootDept.getPkId())){
						deptMap.put(orgRootDept.getPkId(), orgRootDept);
					}
				}
			}else{
				
			}
		}
		
		return deptMap;
	}

	@Override
	public void loadUserRoles(U userInfo) {
		loadUserRoles(userInfo, roleMap);
	}

	/**
	 * 
	 */
	public void loadUserRoles(U userInfo, Map<Integer,RoleInfo> roleMap) {
		List<RoleInfo> list = userInfo.getRoles();

		if(list==null){
			list = new ArrayList<RoleInfo>();
		}else{
			list.clear();
		}
		if(roleMap==null){
			roleMap = new HashMap<Integer, RoleInfo>();
		}
		
		if(userInfo.getPkId()!=null&&userInfo.getPkId()>0){
			List<Integer> roleIds;
			roleIds = getUserRoleService().getRoleIdsByUserId(userInfo.getPkId());
			for(Integer roleId:roleIds){
				RoleInfo roleInfo;
				if(roleMap.containsKey(roleId)){
					roleInfo = roleMap.get(roleId);
				}else{
					roleInfo = getById(roleId);
					roleMap.put(roleId, roleInfo);
				}
				if(roleInfo!=null){
					list.add(roleInfo);
				}
			}
		}
		
		if(userInfo.getRoles()==null){
			userInfo.setRoles(list);
		}
	}

	@Override
	public List<U> getRoleUsers(Integer roleId, Set<Integer> managedOrgIds) {
		List<U> list = new ArrayList<U>();
		
		Set<Integer> roleUserIds = getUserRoleService().getUserIdsByRoleId(roleId);
		for(Integer userId:roleUserIds){
			U userInfo = getUserInfoService().getById(userId);
			if(userInfo!=null){
				getUserInfoService().loadUserDepart(userInfo, null, -1);
				if(managedOrgIds==null){
					list.add(userInfo);
				}else{
					boolean add = false;
					for(Object ud:userInfo.getUserDepts()){
						LocalDept<?, ?> userDept = (LocalDept<?, ?>) ud;
						LocalDept orgRootDept = userDept.getOrgRootDept();
						if (orgRootDept!=null&&managedOrgIds.contains(orgRootDept.getPkId())){
							userInfo.setDepart(userDept);
							add = true;
							break;
						}
					}
					if(add){
						list.add(userInfo);
					}
				}
			}else{
				// 无效授权用户
				try {
					getUserRoleService().unbindUserRoleRelation(roleId, userId);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		return list;
	}

	@Override
	public void bindUserRoleRelation(Integer userId, Integer roleId) throws Exception {
		getUserRoleService().bindUserRoleRelation(userId, roleId);
	}

	@Override
	public void unbindUserRoleRelation(Integer userId, Integer roleId) throws Exception {
		getUserRoleService().unbindUserRoleRelation(userId, roleId);
	}
	
	/**
	 * 获取功能权限组列表
	 * @return
	 */
	public List<FuncInfo> getFuncGroupList() {
		
		FuncInfo example = new FuncInfo();
		example.setParentId(0);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		
		return list;
	}
	
	public FuncInfo getByGroupName(String groupName) {
		FuncInfo funcInfo = null;
		
		FuncInfo example = new FuncInfo();
		example.setName(groupName);
		example.setParentId(0);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		if (list!=null&&list.size()>0){
			funcInfo = list.get(0);
		}
		
		return funcInfo;
	}
	
	public FuncInfo getByFuncCode(String funcCode) {
		FuncInfo funcInfo = null;
		
		FuncInfo example = new FuncInfo();
		example.setFuncCode(funcCode);
		List<FuncInfo> list = getFuncInfoDao().query(example);
		if (list!=null&&list.size()>0){
			funcInfo = list.get(0);
		}
		
		return funcInfo;
	}	
	
	public FuncInfo getSubFuncByFuncCode(FuncInfo parentFunc, String funcCode) {
		FuncInfo funcInfo = null;

		if(parentFunc.getSubFuncs()==null){
			FuncInfo example = new FuncInfo();
			example.setFuncCode(funcCode);
			example.setParentId(parentFunc.getPkId());
			List<FuncInfo> list = getFuncInfoDao().query(example);
			if (list!=null&&list.size()>0){
				funcInfo = list.get(0);
				funcInfo.setParent(parentFunc);
				if (list.size()>1){
					for(int i = 1;i<list.size();i++){
						getFuncInfoDao().delete(list.get(i));
					}
				}
			}
		}else{
			for(FuncInfo f:parentFunc.getSubFuncs()){
				if(f.getFuncCode().equals(funcCode)){
					funcInfo = f;
					break;
				}
			}
		}
		
		return funcInfo;
	}	
	
	/**
	 * 保存角色和所关联的功能项
	 * @param roleId
	 * @param funcIds
	 * @author 舒俊
	 * @throws Exception 
	 */
	@Override
	public void saveRoleFuncs(int roleId, List<Integer> funcIds, U currentUser) throws Exception{
		RoleInfo roleInfo = getById(roleId);
		if(roleInfo==null){
			throw new Exception("指定的角色不存！");
		}
		checkManageRight(currentUser);
		checkUserAuthRange(roleInfo, currentUser);
		
		clearRoleFunc(roleId);
		for(Integer funcId:funcIds){
			FuncInfo funcInfo = getFuncInfoDao().getById(funcId);
			if(funcInfo==null){
				throw new Exception("指定的功能权限不存在！");
			}
			RoleFunc roleFunc = new RoleFunc();
			roleFunc.setRoleId(roleId);
			roleFunc.setState(1);
			roleFunc.setFuncId(funcId);
			getRoleFuncDao().save(roleFunc);
		}
		
	}
	
	/**
	 *  @描述:清除角色对应的功能项
	 *  @方法名称:clearRoleFunc
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:12:11 
	 *  @param roleId
	 * @throws Exception 
	 */
	public void clearRoleFunc(int roleId){
		List<RoleFunc> roleFuncArray = getRoleFuncList(roleId);
		for(int i=0;i<roleFuncArray.size();i++){
			RoleFunc roleFunc = roleFuncArray.get(i);
//			roleFunc.setState(2);
			try {
				getRoleFuncDao().delete(roleFunc);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean deleteById(Integer roleId, @SuppressWarnings("rawtypes") LocalUser currentUser) throws Exception {
		return delete(roleId, (U) currentUser);
	}

	/**
	 * 获得拥有指定功能模块下指定功能权限的用户id集合
	 */
	@Override
	public Set<Integer> getUserIdsByFuncs(String mainFuncCode, String... funcs) throws Exception {
		Set<Integer> userIds = new HashSet<Integer>();

		FuncInfo mainFunc = getMainFuncInfoByCode(mainFuncCode);
				
		if(mainFunc!=null&&funcs!=null){
			for(String funcCode:funcs){
		    	FuncInfo funcInfo = getFuncInfoByRangeCode(mainFunc, funcCode);
		    	
		    	if(funcInfo!=null){
		        	//获取权限码获取有该权限的角色
		        	RoleFunc rolefunc = new RoleFunc();
		        	rolefunc.setState(1);
		        	rolefunc.setFuncId(funcInfo.getPkId());
		        	List<RoleFunc> roleFuncList = getRoleFuncDao().query(rolefunc);
		        	
		        	//过滤重复的UserID,并存放所有的UserID
		        	for (RoleFunc r : roleFuncList) {
		        		//获取角色获取用户
		    			Set<Integer> UserIds = getUserRoleService().getUserIdsByRoleId(r.getRoleId());
		    			for (Integer userId: UserIds) {
		    				if(userId == null){
		    					continue;
		    				}else{
		    					userIds.add(userId);
		    				}
		    			}
		    		}
		    	}
			}
		}
		
		return userIds;
	}

	@Override
	public Page<Purview> purviewManage(Page<Purview> page, U sessionUser) {
		page.getData().clear();
		
		Map<Integer, Purview> cache = new HashMap<Integer, Purview>();
		List<Purview> list = new ArrayList<Purview>();
		List<FuncInfo> funcs = getFuncInfoDao().queryAll();
		for(FuncInfo funcInfo: funcs){
			Purview purview = new Purview();
			purview.setId(funcInfo.getPkId());
			purview.setName(funcInfo.getName());
			purview.setPurviewKey(funcInfo.getFuncCode());
			cache.put(purview.getId(), purview);
		}
		for(FuncInfo funcInfo: funcs){
			Purview purview = cache.get(funcInfo.getPkId());
			if(funcInfo.getParentId()!=null&&funcInfo.getParentId()>0){
				Purview parent = cache.get(funcInfo.getParentId());
				if(parent!=null){
					purview.setParent(parent);
					parent.getPurviews().add(purview);
				}
			}
		}
		for(Purview purview: cache.values()){
			if (purview.getParent()==null){
				list.add(purview);
			}
		}
		
		page.setData(list);
		
		return page;
	}

	@Override
	public Purview purviewSave(Purview item, U sessionUser) {
		Purview itemPo = null;
		
		if(item!=null){
			FuncInfo funcInfo;
			if (item.getId()!=null&&item.getId()>0){
				funcInfo = getFuncInfoDao().getById(item.getId());
				funcInfo.setName(item.getName());
				funcInfo.setFuncCode(item.getPurviewKey());
				
				funcInfo = getFuncInfoDao().update(funcInfo);
			}else{
				funcInfo = new FuncInfo();
				funcInfo.setName(item.getName());
				funcInfo.setParentId(item.getParent()==null?0:item.getParent().getId()==null?0:item.getParent().getId());
				funcInfo.setFuncCode(item.getPurviewKey());
				
				funcInfo = getFuncInfoDao().save(funcInfo);
				item.setId(funcInfo.getPkId());
			}
			itemPo = item;
		}
		
		return itemPo;
	}

	@Override
	public void purviewDel(Integer id, U sessionUser) {
		getFuncInfoDao().delete(id);
	}

	@Override
	public List<LocalRole> getDefaultRolesByOrgId(Integer orgId) {
		List<LocalRole> defaultRoles = new ArrayList<LocalRole>();
		
		List<RoleInfo> list = this.getAllRoleInfo();
		for(RoleInfo localRole:list) {
			if(orgId!=null&&orgId.equals(localRole.getOrgId())&&localRole.getRemark()!=null&&localRole.getRemark().indexOf("基本权限")>=0) {
				defaultRoles.add(localRole);
			}
		}
		
		return defaultRoles;
	}

}
